﻿var _____a;

function Coalesce(value1, value2, value3, value4, value5)
{
	for (var i = 0; i < arguments.length; ++i)
	{
		if (arguments[i] != null)
			return arguments[i];
	}
	return null;
}












function Range(start, end)
{
	this.Start = start;
	this.End = end;
}
Range.prototype.Start = null;
Range.prototype.End = null;















Function._rgxFunctionName = new RegExp("\\s*function\\s+([A-Za-z_$][A-Za-z_$0-9]*)");

function __z__Test()
{
}
__z__Test.prototype = new Array();
var __z__test = new __z__Test();
__z__test.push("asd");
Function._needFakeArray = (__z__test.length == 0);

Function._arrayMembers = ["push", "pop", "sort", "reverse", "shift", "splice", "unshift", "concat", "join", "slice", "indexOf", "lastIndexOf"];
Function._baseClasses = "__baseClasses";
Function._isInterface = "_interface";
Function._inheritConst = "__INHERIT__";
Function.Is = function Is(value, type)
{
	if (value == null) return false;

	if (value instanceof type) return true;

	if (value[Function._baseClasses] == null) return false;
	return value[Function._baseClasses][type] === true;
}
Function.GetName = function GetName(func)
{
	var match = Function._rgxFunctionName.exec(func.toString());
	if (match != null)
		return match[1];
	return null;
}
Function.prototype.MakeInterface = function MakeInterface()
{
	this[Function._isInterface] = true;
}
Function.prototype.Inherit = function Inherit(base, baseName)
{
	var _____a;
	if (_____a)
		base = function() { };

	if (typeof (baseName) === "undefined")
	{
		baseName = Function.GetName(base);
	}
	if (baseName == null || baseName == "") return;

	// STATIC
	this[baseName] = new Object(); // allows for "ChildClass.BaseClass.StaticFunction();"
	for (var staticMember in base) // static functions
	{
		if (staticMember != "prototype" &&
			staticMember != baseName &&
			staticMember != Function._baseClasses &&
			staticMember != Function._isInterface
			&& base[staticMember] != Function.prototype.MakeInterface
			&& base[staticMember] != Function.prototype.Inherit
			&& base[staticMember] != Function.prototype.bind
			)
			this[staticMember] =
				this[baseName][staticMember] =
				 base[staticMember];
	}

	if (base[Function._isInterface] === true)
	{
		for (var memberName in base.prototype)
		{
			delete base.prototype[memberName];
		}
		delete base[Function._isInterface];
	}

	if (this.prototype[Function._baseClasses] == null)
	{
		// main base class

		if (base == Array) // special case
		{
			if (Function._needFakeArray)// IE 6-7 length issue
			{
				this.prototype = { length: 0 };
				for (var iArrayMember = 0; iArrayMember < Function._arrayMembers.length; ++iArrayMember)
				{
					this.prototype[Function._arrayMembers[iArrayMember]] = Array.prototype[Function._arrayMembers[iArrayMember]];
				}
			}
			else
			{
				this.prototype = new base; // inheritance
			}
			this.prototype.toString = this.prototype.join;
		}
		else
		{
			this.prototype = new base(Function._inheritConst); // inheritance
		}
		this.prototype.constructor = this; // reset the constructor

		// the following two lines allow for
		// "ChildClass() { this.BaseClass(...); ... } (call base ctor)
		// the reason the base ctor is wrapped is to avoid having instance members added as static members
		this.prototype[baseName + "_"] = base;
		this.prototype[baseName] = eval("(function " + baseName + "() { return this." + baseName + "_.apply(this, arguments); })");

		for (var instanceMember in base.prototype)
		{
			if (base.prototype instanceof Array && instanceMember == "toString")
				continue;
			this.prototype[baseName][instanceMember] = // this.BaseClass.function.call(this, ....);
				base.prototype[instanceMember];
		}

		this.prototype[Function._baseClasses] = new Object();
	}
	else
	{
		// second or more base class
		this.prototype[baseName] = base; // allows for "ChildClass() { this.BaseClass(...); ... } (call base ctor)
		if (base == Array) // special case
		{
			this.prototype.length = 0;
			for (var iArrayMember = 0; iArrayMember < Function._arrayMembers.length; ++iArrayMember)
			{
				this.prototype[Function._arrayMembers[iArrayMember]] = Array.prototype[Function._arrayMembers[iArrayMember]];
			}
		}
		else
		{
			for (var memberName in base.prototype)
			{
				if (memberName != "constructor")
				{
					this.prototype[memberName] = // this.func(....);
						this.prototype[baseName][memberName] = // this.BaseClass.function.call(this, ....);
						base.prototype[memberName];
				}
			}
		}
	}
	this.prototype[Function._baseClasses][base] = true;
}

Function.IsInherit = function IsInherit(args)
{
	return (args[0] == Function._inheritConst);
}




Function.prototype.bind = function bind(object, argument_list)
{
	var method = this;
	var args = new Array();
	for (var i = 1; i < arguments.length; ++i)
	{
		args.push(arguments[i]);
	}
	return function BoundFunction()
	{
		var args2 = new Array();
		for (var i = 0; i < arguments.length; ++i)
		{
			args2.push(arguments[i]);
		}
		if (arguments.length == 0 && window.event != null && arguments.caller == null)
			args2.push(window.event);
		return method.apply(object, args.concat(args2));
	};
}



















function Throw(msg)
{
	debugger;
	throw new Error(msg);
}










//function Namespace(name)
//{
//	var parts = name.split(".");
//	var path = "";

//	for (var i = 0; i < parts.length; ++i)
//	{
//		if (path == "") path = parts[i]; else path += "." + parts[i];

//		if (eval("typeof(" + path + ")") == "undefined")
//		{
//			eval(path + " = { };");
//		}
//	}
//}
//Namespace("Abc.Def");